package com.heima.behavior.service.impl;

import com.heima.behavior.model.dto.FollowBehaviorDto;
import com.heima.behavior.model.entity.ApFollowBehavior;
import com.heima.behavior.service.ApFollowBehaviorService;
import com.heima.behavior.util.AppUserThreadLocalUtil;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.entity.ApUser;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;

@Service
public class ApFollowBehaviorServiceImpl implements ApFollowBehaviorService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private MongoTemplate mongoTemplate;

    @Override
    public ResponseResult follow(FollowBehaviorDto dto) {
        //1. 校验参数
        if (dto.getAuthorId() == null || AppUserThreadLocalUtil.get() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        ApUser user = AppUserThreadLocalUtil.get();
        //2. 判断用户之前是否已经关注
        String user_follow_key = "USER_FOLLOW_" + user.getId();
        String user_fans_key = "USER_FANS_" + dto.getAuthorId();
        Boolean hasKey = stringRedisTemplate.opsForHash().hasKey(user_follow_key, dto.getAuthorId() + "");
        //2.1 如果之前已经关注 , 现在操作时关注 --- 什么都不做
        if (hasKey && dto.getOperation() == 0) {
            return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
        }
        //2.2 如果之前已经关注 , 现在操作是取消关注  ---- 删除关注数据(redis MongoDB)
        if (hasKey && dto.getOperation() == 1) {
            //2.2.1 删除redis数据
            stringRedisTemplate.opsForHash().delete(user_follow_key, dto.getAuthorId() + "");
            stringRedisTemplate.opsForHash().delete(user_fans_key, user.getId() + "");

            //2.2.2 删除mongodb数据
            Query query = Query.query(Criteria.where("userId").is(user.getId()).and("followId").is(dto.getAuthorId()));
            mongoTemplate.remove(query, ApFollowBehavior.class);
            return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
        }

        //2.3 如果之前没有关注过, 现在操作时关注  --- 保存关注数据 (redis MongoDB)
        //2.3.1 保存关注数据到redis
        stringRedisTemplate.opsForHash().put(user_follow_key, dto.getAuthorId() + "", "1");
        stringRedisTemplate.opsForHash().put(user_fans_key, user.getId() + "", "1");

        //2.3. 保存关注数据到mongodb
        ApFollowBehavior apFollowBehavior = new ApFollowBehavior();
        apFollowBehavior.setId(ObjectId.get().toHexString());
        apFollowBehavior.setArticleId(dto.getArticleId());
        apFollowBehavior.setCreatedTime(new Date());
        apFollowBehavior.setFollowId(dto.getAuthorId());
        apFollowBehavior.setUserId(user.getId());
        mongoTemplate.save(apFollowBehavior);

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
}
